/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package miscelania.almacenamiento;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

/**
 *
 * @author Cristhy
 */
public class PaginaSlot implements Iterable<Elemento>{



      /** El espacio libre en la página. */
        private int espacioLibre;
        /**  numero de elementos de registros de cabecera */
          private int nElementos;
        /** El ID de la página. */
         private IdentificadorPaginaS idPagina;
         /*Lista de punteros de cabecera
          */
         List<Elemento> cabeceras;

    public int getEspacioLibre() {
        return espacioLibre;
    }


    public IdentificadorPaginaS getIdPagina() {
        return idPagina;
    }


    public int getnElementos() {
        return nElementos;
    }


    public PaginaSlot( IdentificadorPaginaS idPagina) {

        this.idPagina = idPagina;
        this.nElementos=0;
        espacioLibre = 4096 - Convert.INT_SIZE;
        cabeceras= new ArrayList<Elemento>();

    }
      
     public boolean hayEspacio(Tupla t,Relacion rel) {
        return espacioLibre >= GestorIOTupla.byteSize(rel, t);//si hay espacio para la nueva tupla
    }
     public void adicionarTupla(Tupla tupla,Relacion rel)
            throws ArrayIndexOutOfBoundsException {

        if (hayEspacio(tupla,rel)) {

            Elemento e = new Elemento(tupla, GestorIOTupla.byteSize(rel, tupla), rel);
            cabeceras.add(e);
            espacioLibre -= GestorIOTupla.byteSize(rel, tupla);//resto el espacio libre del tamaño de la tupla
            nElementos++;
        } else {
           // IdentificadorPaginaS idn= new IdentificadorPaginaS(idPagina.getNombreArchivo(), idPagina.getNumero()+1);
           throw new ArrayIndexOutOfBoundsException("no hay espacio en la página.");
        }
    }



    public boolean puedeCambiar(int index, Tupla nt,Relacion rel) {

        return (espacioLibre
                + GestorIOTupla.byteSize(cabeceras.get(index).getRelacion(), cabeceras.get(index).getTupla())
                - GestorIOTupla.byteSize(rel, nt)) >= 0;
    }



    public Tupla recuperarTupla(int index) {

        return cabeceras.get(index).getTupla();
    }



    @Override
    public Iterator<Elemento> iterator() {
        return new IteradorDePagina();
    }


    private  class IteradorDePagina implements Iterator<Elemento> {
         /** El actual indice del iterator. */
        private int indiceActual;

        /**
         * Constructor de un nuevo iterator para el contenido de la página.
         */
        public IteradorDePagina() {
            indiceActual = 0;
        }


        @Override
        public boolean hasNext() {
            return indiceActual < cabeceras.size();
        }

        @Override
        public Elemento next() {
            return cabeceras.get(indiceActual++);
        }

        @Override
        public void remove() {
            int size = GestorIOTupla.byteSize(cabeceras.get(indiceActual).getRelacion(),
                    cabeceras.get(indiceActual).getTupla());
            espacioLibre += size;
            cabeceras.remove(indiceActual);
        }
            @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();
        sb.append("pagina: ").append(getIdPagina()).append(", tuplas: {\n");
        int tid = 0;
       for (int i = 0; i < cabeceras.size(); i++) {
           Elemento elemento = cabeceras.get(i);
            sb.append("\t").append(tid++).append(": ").append(elemento.getTupla().toString()).append("\n");
        }
        
        sb.append("}");
        return sb.toString();
    }
    
    }
}
